<!doctype html>
<html lang="en">
        <head>
                <meta charset="utf-8">
                <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
                <meta name="generator" content="pdoc 0.9.1" />
                <title>tk_sudoku_game API documentation</title>
                <meta name="description" content="This module is a full sudoku game with GUI using `tkinter`. It also provides a solution for the loaded board …" />
                <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
                <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
                <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
                <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
                <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
                <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
                <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
                <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
                <link rel="stylesheet" type="text/css" href="github-style.css">
        </head>
        <body>
                <main>
                        <article id="content">
                                <header>
                                        <h1 class="title">Module <code>tk_sudoku_game</code></h1>
                                </header>
                                <section id="section-intro">
                                        <p>This module is a full sudoku game with GUI using <code>tkinter</code>. It also provides a solution for the loaded board.</p>
                                        <p><strong>External modules</strong>: <code>copy</code>, <code>threading</code>, <code>random</code>, <code>tkinter</code></p>
                                        <p><code>Compatible with Python3.7 or higher</code></p>
                                        <p><em>Repository:</em> <a href="https://github.com/rickfernandes/sudoku_solver">https://github.com/rickfernandes/sudoku_solver</a></p>
                                        <details class="source">
                                        <summary>
                                        <span>Expand source code</span>
                                        </summary>
                                        <pre><code class="python"># -*- coding: utf-8 -*-
                                                &#34;&#34;&#34;
                                                This module is a full sudoku game with GUI using `tkinter`. It also provides a solution for the loaded board.
                                                __External modules__: `copy`, `threading`, `random`, `tkinter`
                                                `Compatible with Python3.7 or higher`\n
                                                _Repository:_ https://github.com/rickfernandes/sudoku_solver
                                                &#34;&#34;&#34;
                                                from tkinter import Button, Tk, Canvas, Frame, BOTH, X, ALL, ttk
                                                from copy import deepcopy
                                                from threading import Thread, enumerate
                                                from random import randint
                                                # Colour and design
                                                GRID_COLOR = &#39;#2C75A3&#39;
                                                &#34;&#34;&#34;Grid colour&#34;&#34;&#34;
                                                BACKGROUND_COLOR = &#39;#EEB8B8&#39;
                                                &#34;&#34;&#34;Background colour&#34;&#34;&#34;
                                                NUMBER_COLOR = &#39;#59B5F0&#39;
                                                &#34;&#34;&#34;Numbers colour&#34;&#34;&#34;
                                                CURSOR_COLOR = &#39;#F0ED41&#39;
                                                &#34;&#34;&#34;Cursor border colour&#34;&#34;&#34;
                                                FONT_TYPE = &#39;Tahoma&#39;
                                                &#34;&#34;&#34;Numbers font&#34;&#34;&#34;
                                                CELL_SIZE = 60
                                                &#34;&#34;&#34;Sudoku board cell size&#34;&#34;&#34;
                                                # Constant global variables
                                                BUTTONS_SIZE = 75
                                                HEIGHT = WIDTH = 9 * CELL_SIZE + 6
                                                def WaitThread():
                                                        &#34;&#34;&#34;Function to wait process thread responsible for calculation the solutions.
                                                        Args:
                                                                __None__
                                                        Returns:
                                                                __None__
                                                        &#34;&#34;&#34;
                                                        while len(enumerate()) &gt; 1: True
                                                def InvertBoard(board):
                                                        &#34;&#34;&#34;Function to transpose the imported sudoku board to match the game UI.
                                                        Args:
                                                                `board` (matrix): valid sudoku board.
                                                        Returns:
                                                                Inverted board matrix
                                                        &#34;&#34;&#34;
                                                        return [[board[j][i] for j in range(len(board))] for i in range(len(board[0]))]
                                                class MainWindow(Tk):
                                                        &#34;&#34;&#34;Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.&#34;&#34;&#34;
                                                        def __init__(self,board):
                                                                &#34;&#34;&#34;It&#39;s the main game window that contains the sudoku game, sudoku frame (where numbers and grid will be drawn)
                                                                and buttons frame (where the buttons will be packed).
                                                                Uses super class `Tk` from module `tkinter`
                                                                &#34;&#34;&#34;
                                                                Tk.__init__(self)
                                                                # Initiates the Tk instance in self
                                                                self.body = Body()
                                                                &#34;&#34;&#34;`Body` class&#34;&#34;&#34;
                                                                self.cursor = Cursor()
                                                                &#34;&#34;&#34;`Cursor` class&#34;&#34;&#34;
                                                                self.game = Game(InvertBoard(board))
                                                                &#34;&#34;&#34;`Game` class with `InvertBoard`&#34;&#34;&#34;
                                                                self.buttons = Buttons(self)
                                                                &#34;&#34;&#34;`Cursor` class&#34;&#34;&#34;
                                                                self.Config()
                                                                &#34;&#34;&#34;Calls `Config` to configure the window&#34;&#34;&#34;
                                                                self.InitiateGame()
                                                                &#34;&#34;&#34;Calls `InitiateGame` to start the sudoku game&#34;&#34;&#34;
                                                        def Config(self):
                                                                &#34;&#34;&#34;Method called when `MainWindow` instance is initiate. Configures title, window size and background colour.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.title(&#39;SUDOKU&#39;)
                                                                self.geometry(f&#39;{WIDTH+2}x{HEIGHT+2 + BUTTONS_SIZE}&#39;)
                                                                self.config(bg=BACKGROUND_COLOR)
                                                                print(&#39;main window loaded and configured&#39;)
                                                        def InitiateGame(self):
                                                                &#34;&#34;&#34;Method called when the games starts or is reset with clear board button.
                                                                It calls `Binder`, `DrawGrid`, `DrawNumbers` (with `original_board`), `DrawButtons` and, packs `body` and `buttons`.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.Binder()
                                                                self.body.DrawGrid()
                                                                self.body.DrawNumbers(self.game.original_board,GRID_COLOR)
                                                                self.buttons.DrawButtons()
                                                                self.body.pack(fill=X)
                                                                self.buttons.pack(fill=X)
                                                                print(&#39;game initiated&#39;)
                                                        def Binder(self):
                                                                &#34;&#34;&#34;Method to bind/map keyboard and mouse clicks to their methods.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def __MoveHandler(event,window=self):
                                                                        # Gets the mouse position and moves/draws the cursor there
                                                                        if str(event.type) == &#39;ButtonPress&#39;:
                                                                                x, y = int((event.x) / CELL_SIZE), int((event.y) / CELL_SIZE)
                                                                                if x &gt; 8: x = 8
                                                                                if y &gt; 8: y = 8
                                                                                self.cursor.x_pos, self.cursor.y_pos = x, y
                                                                        self.cursor.MoveCursor(event,window)
                                                                def __InsertHandler(event):
                                                                        # Gets the stroked key and handles what to do with it
                                                                        if event.keysym == &#39;Escape&#39;: self.HardReset()
                                                                        if event.keysym == &#39;BackSpace&#39;:self.body.DeleteNumber(self.game, self.cursor.x_pos,self.cursor.y_pos)
                                                                        elif not self.game.gameover: self.body.InsertNumber(event.keysym,self.game,self.cursor.x_pos,self.cursor.y_pos)
                                                                        
                                                                        self.game.isGameOver()
                                                                        #  Checks if the game is over and draws the game over text
                                                                        if self.game.gameover:
                                                                                self.body.InsertMiddleText(&#39;Game over&#39;)
                                                                        else:
                                                                                self.body.delete(&#39;gameover&#39;)
                                                                self.body.bind(&#39;&lt;Button-1&gt;&#39;,__MoveHandler)
                                                                for key in [&#39;&lt;Left&gt;&#39;,&#39;&lt;Right&gt;&#39;,&#39;&lt;Up&gt;&#39;,&#39;&lt;Down&gt;&#39;]:
                                                                        self.bind(key,__MoveHandler)
                                                                self.bind(&#39;&lt;Key&gt;&#39;,__InsertHandler)
                                                        def HardReset(self):
                                                                &#34;&#34;&#34;Method to completely reset the game. 
                                                                Calls `ResetGame`, delete everything inside `Body` frame and reset `inserted_numbers` array.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.game.ResetGame()
                                                                self.body.delete(ALL)
                                                                self.body.inserted_numbers = []
                                                                self.InitiateGame()
                                                class Body(Canvas):
                                                        &#34;&#34;&#34;Canvas widget to display graphical elements like lines or text
                                                        Uses super class `Canvas` from module `tkinter`&#34;&#34;&#34;
                                                        def __init__(self):
                                                                &#34;&#34;&#34;Constructs a canvas widget&#34;&#34;&#34;
                                                                Canvas.__init__(self)
                                                                # Initiate `Canvas` instance
                                                                self.config(bg=BACKGROUND_COLOR,height=HEIGHT-4)
                                                                # Configures background colour.
                                                                self.inserted_numbers = []
                                                                &#34;&#34;&#34;Array that keeps track of the inserted numbers sequence.&#34;&#34;&#34;
                                                        def DrawGrid(self):
                                                                &#34;&#34;&#34;Method to draw sudoku board grid. 
                                                                
                                                                Args:
                                                                        `self` (Body): `Body` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                for i in range(0,10):
                                                                        x = i * CELL_SIZE
                                                                        if i % 3 == 0:
                                                                                self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, width=2)
                                                                                self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, width=2)
                                                                        else:
                                                                                pass
                                                                                self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, dash=(1,1))
                                                                                self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, dash=(1,1))
                                                        def DrawNumbers(self,board,color):
                                                                &#34;&#34;&#34;Method to draw original (i.e. loaded) sudoku board numbers. 
                                                                
                                                                Args:
                                                                        `self` (Body): `Body` object.\n
                                                                        `board` (matrix): valid sudoku board, loaded at the beginning of the program.\n
                                                                        `color` (str): `GRID_COLOR` colour.\n
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.delete(&#39;numbers&#39;)
                                                                # delete all numbers with tag &#39;numbers&#39;
                                                                for i in range(9):
                                                                        for j in range(9):
                                                                                x, y = i * CELL_SIZE + CELL_SIZE / 2 + 4, j * CELL_SIZE + CELL_SIZE / 2 + 4
                                                                                n = board[i][j]
                                                                                if n != 0:
                                                                                        self.create_text(x, y, text=n, tags=&#39;numbers&#39;,fill=GRID_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))
                                                        def InsertNumber(self,key,game,x_pos,y_pos,**kwargs):
                                                                &#34;&#34;&#34;Method to draw the inserted number in a valid position of the sudoku board.
                                                                The number will only be inserted if the position on `original_board` is `0`, `PossibleMove` returns True and if the number is not `0`.
                                                                
                                                                Args:
                                                                        `self` (Body): `Body` object.\n
                                                                        `key` (str): comes from binder. If not an integer, it will be ignored.\n
                                                                        `game` (Game): `Game` object.\n
                                                                        `x_pos` (int): x position of the number to be inserted.\n
                                                                        `y_pos` (int): y position of the number to be inserted.\n
                                                                        `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                x, y = 4 + x_pos * CELL_SIZE + CELL_SIZE / 2, 4 + y_pos * CELL_SIZE + CELL_SIZE / 2
                                                                try: move_type = kwargs[&#39;move_type&#39;]
                                                                except:  move_type = &#39;&#39;
                                                                try: int(key)
                                                                except: pass
                                                                else:
                                                                        number = int(key)
                                                                        if game.PossibleMove(number,x_pos,y_pos) and game.original_board[x_pos][y_pos] == 0 and number != 0:
                                                                                self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                                                game.board[x_pos][y_pos] = number
                                                                                self.create_text(x, y, text=number, tags=f&#39;number{x_pos}x{y_pos}&#39;, fill=NUMBER_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))
                                                                                if move_type != &#39;backwards&#39;:
                                                                                        self.inserted_numbers.append([x_pos,y_pos,number,&#39;insert&#39;])
                                                        def DeleteNumber(self,game,x_pos,y_pos,**kwargs):
                                                                &#34;&#34;&#34;Method to delete a number in a valid position of the sudoku board.
                                                                
                                                                Args:
                                                                        `self` (Body): `Body` object.\n
                                                                        `game` (Game): `Game` object.\n
                                                                        `x_pos` (int): x position of the number to be deleted.\n
                                                                        `y_pos` (int): y position of the number to be deleted.\n
                                                                        `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                try: move_type = kwargs[&#39;move_type&#39;]
                                                                except:  move_type = &#39;&#39;
                                                                if move_type != &#39;backwards&#39;:
                                                                        self.inserted_numbers.append([x_pos,y_pos,game.board[x_pos][y_pos],&#39;delete&#39;])
                                                                game.board[x_pos][y_pos] = 0
                                                                self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                                game.gameover = False
                                                        def InsertMiddleText(self,text):
                                                                &#34;&#34;&#34;Method to insert a text in the middle of `Body`.
                                                                
                                                                Args:
                                                                        `self` (Body): `Body` object.\n
                                                                        `text` (str): text to be inserted/drawn object.\n
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.delete(&#39;cursor&#39;)
                                                                text = self.create_text(WIDTH / 2,HEIGHT / 2 - int(CELL_SIZE/2), text=text, font=(FONT_TYPE, int(CELL_SIZE/2)),fill=CURSOR_COLOR,tags=&#39;gameover&#39;)
                                                                rect = self.create_rectangle(self.bbox(text),fill=BACKGROUND_COLOR,tags=&#39;gameover&#39;)
                                                                self.tag_lower(rect,text)
                                                class Cursor(): 
                                                        &#34;&#34;&#34;Cursor widget to display/select the cells in the sudoku board.&#34;&#34;&#34;
                                                        def __init__(self):
                                                                self.x_pos = 0
                                                                &#34;&#34;&#34;Column position of the cursor&#34;&#34;&#34;
                                                                self.y_pos = 0
                                                                &#34;&#34;&#34;Row position of the cursor&#34;&#34;&#34;
                                                                self.number = 0
                                                        def DrawCursor(self,body):
                                                                &#34;&#34;&#34;Method to draw the cursor in positions `x_pos` and `y_pos`. 
                                                                
                                                                Args:
                                                                        `body` (Body): `Body` object.
                                                                        `self` (Cursor): `Cursor` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                x, y = 4 + (self.x_pos * CELL_SIZE), 4 + (self.y_pos * CELL_SIZE)
                                                                body.delete(&#39;cursor&#39;)
                                                                body.create_rectangle(x, y, x + CELL_SIZE, y + CELL_SIZE, outline=CURSOR_COLOR, tags=&#39;cursor&#39;,width=2)
                                                        def MoveCursor(self,event,window):
                                                                &#34;&#34;&#34;Method to move cursor positions `x_pos` and `y_pos` according to the arrow keyboard input.
                                                                The movement skips cells with numbers from original board.
                                                                
                                                                Args:
                                                                        `self` (Cursor): `Cursor` object.
                                                                        `body` (Window): `MainWindow` object.
                                                                        `event` (bind.event): event from `Tk.bind` method.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                moves = {&#39;Up&#39;:[0,-1],&#39;Down&#39;:[0,1],&#39;Left&#39;:[-1,0],&#39;Right&#39;:[1,0],}
                                                                x, y = self.x_pos, self.y_pos
                                                                while event.keysym in list(moves):
                                                                        x += moves[event.keysym][0]
                                                                        y += moves[event.keysym][1]
                                                                        if x &lt;= 8 and x &gt;= 0 and y &lt;= 8 and y &gt;= 0:
                                                                                if window.game.original_board[x][y] == 0:
                                                                                        self.x_pos, self.y_pos = x, y
                                                                                        break
                                                                        else: break
                                                                if window.game.original_board[self.x_pos][self.y_pos] == 0:
                                                                        self.DrawCursor(window.body)
                                                class Game():
                                                        &#34;&#34;&#34;Contains all necessary info for the correct handling of the sudoku game.
                                                        Takes one parameter `board` (a valid sudoku board) to be initiated.&#34;&#34;&#34;
                                                        def __init__(self,board):
                                                                self.gameover = False
                                                                &#34;&#34;&#34;Boolean value to determine if the game is over&#34;&#34;&#34;
                                                                self.board = board
                                                                &#34;&#34;&#34;Valid sudoku board. Will be updated with the number inserted by the user.&#34;&#34;&#34;
                                                                self.original_board = deepcopy(board)
                                                                &#34;&#34;&#34;Copy of the `board` used to initiate the class. Will not change throughout the game.&#34;&#34;&#34;
                                                                self.original_solutions = []
                                                                &#34;&#34;&#34;Array with all possible solutions for the original board. It&#39;s calculated at the game start and will not change throughout the game.&#34;&#34;&#34;
                                                                self.solutions = []
                                                                &#34;&#34;&#34;Array with possible solutions for current `board` (i.e. board with inserted numbers.&#34;&#34;&#34;
                                                                Thread(target=self.SudokuSolver).start()
                                                                # Thread initiate to calculate all possible solutions for original board.
                                                        def PossibleMove(self, number, x_pos, y_pos):
                                                                &#34;&#34;&#34;Method to check if `number` can be inserted in positions `x_pos` &amp; `y_pos` of the `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.\n
                                                                        `number` (int): number to be inserted.\n
                                                                        `x_pos` (int): board column.\n
                                                                        `y_pos` (int): board row.\n
                                                                Returns:
                                                                        boolean: can `n` be inserted. _False_ if not possible. _True_ otherwise.
                                                                &#34;&#34;&#34;
                                                                for i in range(9):
                                                                        if self.board[x_pos][i] == number or self.board[i][y_pos] == number: return False
                                                                x_temp, y_temp = (x_pos//3)*3, (y_pos//3)*3
                                                                for i in range(3):
                                                                        for j in range(3):
                                                                                if self.board[x_temp+i][y_temp+j] == number: return False
                                                                return True
                                                        def RemoveInvalidSolutions(self):
                                                                &#34;&#34;&#34;Method to remove all invalid solutions for current `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def MatchSolution(board,solution):
                                                                        # Matches the solution with the board.
                                                                        # If solution cannot be applied to board, returns False
                                                                        for x in range(9):
                                                                                for y in range(9):
                                                                                        if board[x][y] != 0 and board[x][y] != solution[x][y]:
                                                                                                return False
                                                                        return True
                                                                for s in range(len(self.solutions)-1,-1,-1):
                                                                        # loops through all solutions and remove the invalid ones.
                                                                        if not MatchSolution(self.board,self.solutions[s]):
                                                                                del self.solutions[s]
                                                        def SudokuSolver(self):
                                                                &#34;&#34;&#34;Method to solve the sudoku board, inserting all solutions into `original_solutions`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def QueueBlank(board):
                                                                        # Creates a queue with the blank positions (i.e. `0`s) of grid and the quantity of blank spaces on its row, column and square.
                                                                        queue = {}
                                                                        blanks = 0
                                                                        for r in range(9):
                                                                                for c in range(9):
                                                                                        if board[r][c] == 0:
                                                                                                for i in range(9):
                                                                                                        if board[i][c] == 0: blanks += 1
                                                                                                        if board[r][i] == 0: blanks += 1
                                                                                                r_temp, c_temp = (r//3) * 3, (c//3) * 3
                                                                                                for i in range(3):
                                                                                                        for j in range(3):
                                                                                                                if board[r_temp+i][c_temp+j] == 0: blanks += 1
                                                                                        if blanks != 0: queue.update({(r,c):blanks})
                                                                                        blanks = 0
                                                                        temp_queue = sorted(queue.items(), key=lambda x: x[1])
                                                                        return [v[0] for v in temp_queue]
                                                                def SolveSudoku(queue):
                                                                        # Basic sudoku solver algorithm using recursion.
                                                                        if queue:
                                                                                row, col = queue[0][0], queue[0][1]
                                                                                for n in range(9):
                                                                                        if self.PossibleMove(n+1,row,col):
                                                                                                self.board[row][col] = n+1
                                                                                                SolveSudoku(queue[1:])
                                                                                                self.board[row][col] = 0
                                                                                return 
                                                                        solution = deepcopy(self.board)
                                                                        self.original_solutions.append(solution)
                                                                SolveSudoku(QueueBlank(self.board))
                                                                print(&#39;solutions thread finished&#39;)
                                                        def isGameOver(self):
                                                                &#34;&#34;&#34;Method to check there are `0` in board, if not the game is over. Stores the value in `gameover` variable of `Game`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                rows = []
                                                                for row in self.board: 
                                                                        rows += row
                                                                if 0 not in rows:
                                                                        self.gameover = True
                                                                else:
                                                                        self.gameover = False
                                                        def ResetGame(self):
                                                                &#34;&#34;&#34;Method to reset `board` to `original_board` and `solutions` to `original_solutions`.
                                                        
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.board = deepcopy(self.original_board)
                                                                self.solutions = deepcopy(self.original_solutions)
                                                class Buttons(Frame):
                                                        &#34;&#34;&#34;Frame widget which contains the buttons. Has the `MainWindow` object as argument.
                                                        &#34;&#34;&#34;
                                                        def __init__(self,mainwindow):
                                                                &#34;&#34;&#34;Uses super class `Frame` from module `tkinter`&#34;&#34;&#34;
                                                                Frame.__init__(self)
                                                                &#34;&#34;&#34;Initiates Frame instance in self.&#34;&#34;&#34;
                                                                self.clear_button = ttk.Button(self, text=&#39;Clear numbers&#39;,command=lambda: self.ClearBoard(mainwindow))
                                                                &#34;&#34;&#34;Button that call `ClearBoard` method&#34;&#34;&#34;
                                                                self.solve_button = ttk.Button(self, text=&#39;Solve sudoku&#39;,command=lambda: self.SolveBoard(mainwindow))
                                                                &#34;&#34;&#34;Button that call `SolveBoard` method&#34;&#34;&#34;
                                                                self.back_button = ttk.Button(self, text=&#39;Move back&#39;,command=lambda: self.MoveBackwards(mainwindow))
                                                                &#34;&#34;&#34;Button that call `MoveBackwards` method&#34;&#34;&#34;
                                                        def ClearBoard(self,mainwindow):
                                                                &#34;&#34;&#34;Method to clear/reset `board`. Calls `HardReset` method.
                                                        
                                                                Args:
                                                                        `self` (Buttons): `Buttons` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                WaitThread()
                                                                mainwindow.HardReset()
                                                                print(&#39;board cleared&#39;)
                                                        def SolveBoard(self,mainwindow):
                                                                &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws the solution (if it exists).
                                                                Args:
                                                                        `self` (Buttons): `Buttons` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                WaitThread()
                                                                game = mainwindow.game
                                                                game.solutions = deepcopy(game.original_solutions)
                                                                game.RemoveInvalidSolutions()
                                                                if game.solutions == []:
                                                                        mainwindow.body.InsertMiddleText(&#39;No possible solutions&#39;)
                                                                else:
                                                                        mainwindow.body.delete(&#39;gameover&#39;)
                                                                        r = randint(0,len(game.solutions)-1)
                                                                        for x in range(9):
                                                                                for y in range(9):
                                                                                        if game.solutions[r][x][y] != game.original_board[x][y]:
                                                                                                mainwindow.body.InsertNumber(game.solutions[r][x][y],game,x,y)
                                                        def MoveBackwards(self,mainwindow):
                                                                &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws a solution (if there are any).
                                                                Args:
                                                                        `self` (Buttons): `Buttons` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                if mainwindow.body.inserted_numbers != []:
                                                                        last_move = mainwindow.body.inserted_numbers[-1]
                                                                        if last_move[-1] == &#39;insert&#39;:
                                                                                mainwindow.body.DeleteNumber(mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                        elif last_move[-1] == &#39;delete&#39;:
                                                                                mainwindow.body.InsertNumber(last_move[2],mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                        mainwindow.body.inserted_numbers = mainwindow.body.inserted_numbers[0:-1]
                                                                mainwindow.body.delete(&#39;gameover&#39;)
                                                                
                                                        def DrawButtons(self):
                                                                &#34;&#34;&#34;Method to pack all buttons&#34;&#34;&#34;
                                                                self.clear_button.pack(fill=X)
                                                                self.solve_button.pack(fill=X)
                                                                self.back_button.pack(fill=X)
                                                if __name__ == &#39;__main__&#39;:
                                                        board = [
                                                                [0,0,0,0,0,0,0,0,0],
                                                                [0,0,0,0,0,0,0,0,0],
                                                                [0,0,0,0,0,0,0,0,0],
                                                                [8,2,9,7,0,1,5,0,0],
                                                                [4,5,6,8,9,3,7,0,0],
                                                                [7,1,3,4,2,5,8,0,0],
                                                                [9,6,1,3,5,4,2,0,0],
                                                                [0,0,7,6,0,9,4,0,0],
                                                                [0,0,5,2,8,7,6,0,0]
                                                                ]
                                        MainWindow(board).mainloop()</code></pre>
                                        </details>
                                </section>
                                <section>
                                </section>
                                <section>
                                        <h2 class="section-title" id="header-variables">Global variables</h2>
                                        <dl>
                                                <dt id="tk_sudoku_game.BACKGROUND_COLOR"><code class="name">var <span class="ident">BACKGROUND_COLOR</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Background colour</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.CELL_SIZE"><code class="name">var <span class="ident">CELL_SIZE</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Sudoku board cell size</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.CURSOR_COLOR"><code class="name">var <span class="ident">CURSOR_COLOR</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Cursor border colour</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.FONT_TYPE"><code class="name">var <span class="ident">FONT_TYPE</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Numbers font</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.GRID_COLOR"><code class="name">var <span class="ident">GRID_COLOR</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Grid colour</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.NUMBER_COLOR"><code class="name">var <span class="ident">NUMBER_COLOR</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Numbers colour</p></div>
                                                </dd>
                                        </dl>
                                </section>
                                <section>
                                        <h2 class="section-title" id="header-functions">Functions</h2>
                                        <dl>
                                                <dt id="tk_sudoku_game.InvertBoard"><code class="name flex">
                                                <span>def <span class="ident">InvertBoard</span></span>(<span>board)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Function to transpose the imported sudoku board to match the game UI.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>board</code> (matrix): valid sudoku board.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p>Inverted board matrix</p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def InvertBoard(board):
                                                                &#34;&#34;&#34;Function to transpose the imported sudoku board to match the game UI.
                                                                Args:
                                                                        `board` (matrix): valid sudoku board.
                                                                Returns:
                                                                        Inverted board matrix
                                                                &#34;&#34;&#34;
                                                return [[board[j][i] for j in range(len(board))] for i in range(len(board[0]))]</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.WaitThread"><code class="name flex">
                                                <span>def <span class="ident">WaitThread</span></span>(<span>)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Function to wait process thread responsible for calculation the solutions.</p>
                                                <h2 id="args">Args</h2>
                                                <p><strong>None</strong></p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def WaitThread():
                                                                &#34;&#34;&#34;Function to wait process thread responsible for calculation the solutions.
                                                                Args:
                                                                        __None__
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                while len(enumerate()) &gt; 1: True</code></pre>
                                                </details>
                                                </dd>
                                        </dl>
                                </section>
                                <section>
                                        <h2 class="section-title" id="header-classes">Classes</h2>
                                        <dl>
                                                <dt id="tk_sudoku_game.Body"><code class="flex name class">
                                                <span>class <span class="ident">Body</span></span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Canvas widget to display graphical elements like lines or text
                                                Uses super class <code>Canvas</code> from module <code>tkinter</code></p>
                                                <p>Constructs a canvas widget</p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">class Body(Canvas):
                                                                &#34;&#34;&#34;Canvas widget to display graphical elements like lines or text
                                                                Uses super class `Canvas` from module `tkinter`&#34;&#34;&#34;
                                                                def __init__(self):
                                                                        &#34;&#34;&#34;Constructs a canvas widget&#34;&#34;&#34;
                                                                        Canvas.__init__(self)
                                                                        # Initiate `Canvas` instance
                                                                        self.config(bg=BACKGROUND_COLOR,height=HEIGHT-4)
                                                                        # Configures background colour.
                                                                        self.inserted_numbers = []
                                                                        &#34;&#34;&#34;Array that keeps track of the inserted numbers sequence.&#34;&#34;&#34;
                                                                def DrawGrid(self):
                                                                        &#34;&#34;&#34;Method to draw sudoku board grid. 
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        for i in range(0,10):
                                                                                x = i * CELL_SIZE
                                                                                if i % 3 == 0:
                                                                                        self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, width=2)
                                                                                        self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, width=2)
                                                                                else:
                                                                                        pass
                                                                                        self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, dash=(1,1))
                                                                                        self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, dash=(1,1))
                                                                def DrawNumbers(self,board,color):
                                                                        &#34;&#34;&#34;Method to draw original (i.e. loaded) sudoku board numbers. 
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `board` (matrix): valid sudoku board, loaded at the beginning of the program.\n
                                                                                `color` (str): `GRID_COLOR` colour.\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.delete(&#39;numbers&#39;)
                                                                        # delete all numbers with tag &#39;numbers&#39;
                                                                        for i in range(9):
                                                                                for j in range(9):
                                                                                        x, y = i * CELL_SIZE + CELL_SIZE / 2 + 4, j * CELL_SIZE + CELL_SIZE / 2 + 4
                                                                                        n = board[i][j]
                                                                                        if n != 0:
                                                                                                self.create_text(x, y, text=n, tags=&#39;numbers&#39;,fill=GRID_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))
                                                                def InsertNumber(self,key,game,x_pos,y_pos,**kwargs):
                                                                        &#34;&#34;&#34;Method to draw the inserted number in a valid position of the sudoku board.
                                                                        The number will only be inserted if the position on `original_board` is `0`, `PossibleMove` returns True and if the number is not `0`.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `key` (str): comes from binder. If not an integer, it will be ignored.\n
                                                                                `game` (Game): `Game` object.\n
                                                                                `x_pos` (int): x position of the number to be inserted.\n
                                                                                `y_pos` (int): y position of the number to be inserted.\n
                                                                                `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        x, y = 4 + x_pos * CELL_SIZE + CELL_SIZE / 2, 4 + y_pos * CELL_SIZE + CELL_SIZE / 2
                                                                        try: move_type = kwargs[&#39;move_type&#39;]
                                                                        except:  move_type = &#39;&#39;
                                                                        try: int(key)
                                                                        except: pass
                                                                        else:
                                                                                number = int(key)
                                                                                if game.PossibleMove(number,x_pos,y_pos) and game.original_board[x_pos][y_pos] == 0 and number != 0:
                                                                                        self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                                                        game.board[x_pos][y_pos] = number
                                                                                        self.create_text(x, y, text=number, tags=f&#39;number{x_pos}x{y_pos}&#39;, fill=NUMBER_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))
                                                                                        if move_type != &#39;backwards&#39;:
                                                                                                self.inserted_numbers.append([x_pos,y_pos,number,&#39;insert&#39;])
                                                                def DeleteNumber(self,game,x_pos,y_pos,**kwargs):
                                                                        &#34;&#34;&#34;Method to delete a number in a valid position of the sudoku board.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `game` (Game): `Game` object.\n
                                                                                `x_pos` (int): x position of the number to be deleted.\n
                                                                                `y_pos` (int): y position of the number to be deleted.\n
                                                                                `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        try: move_type = kwargs[&#39;move_type&#39;]
                                                                        except:  move_type = &#39;&#39;
                                                                        if move_type != &#39;backwards&#39;:
                                                                                self.inserted_numbers.append([x_pos,y_pos,game.board[x_pos][y_pos],&#39;delete&#39;])
                                                                        game.board[x_pos][y_pos] = 0
                                                                        self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                                        game.gameover = False
                                                                def InsertMiddleText(self,text):
                                                                        &#34;&#34;&#34;Method to insert a text in the middle of `Body`.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `text` (str): text to be inserted/drawn object.\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.delete(&#39;cursor&#39;)
                                                                        text = self.create_text(WIDTH / 2,HEIGHT / 2 - int(CELL_SIZE/2), text=text, font=(FONT_TYPE, int(CELL_SIZE/2)),fill=CURSOR_COLOR,tags=&#39;gameover&#39;)
                                                                        rect = self.create_rectangle(self.bbox(text),fill=BACKGROUND_COLOR,tags=&#39;gameover&#39;)
                                                self.tag_lower(rect,text)</code></pre>
                                                </details>
                                                <h3>Ancestors</h3>
                                                <ul class="hlist">
                                                        <li>tkinter.Canvas</li>
                                                        <li>tkinter.Widget</li>
                                                        <li>tkinter.BaseWidget</li>
                                                        <li>tkinter.Misc</li>
                                                        <li>tkinter.Pack</li>
                                                        <li>tkinter.Place</li>
                                                        <li>tkinter.Grid</li>
                                                        <li>tkinter.XView</li>
                                                        <li>tkinter.YView</li>
                                                </ul>
                                                <h3>Instance variables</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Body.inserted_numbers"><code class="name">var <span class="ident">inserted_numbers</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Array that keeps track of the inserted numbers sequence.</p></div>
                                                        </dd>
                                                </dl>
                                                <h3>Methods</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Body.DeleteNumber"><code class="name flex">
                                                        <span>def <span class="ident">DeleteNumber</span></span>(<span>self, game, x_pos, y_pos, **kwargs)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to delete a number in a valid position of the sudoku board.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.</p>
                                                        <p><code>game</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                        <p><code>x_pos</code> (int): x position of the number to be deleted.</p>
                                                        <p><code>y_pos</code> (int): y position of the number to be deleted.</p>
                                                        <p><code>kwargs['move_type']</code> (str): if <code>backwards</code> does not update <code>inserted_numbers</code></p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def DeleteNumber(self,game,x_pos,y_pos,**kwargs):
                                                                        &#34;&#34;&#34;Method to delete a number in a valid position of the sudoku board.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `game` (Game): `Game` object.\n
                                                                                `x_pos` (int): x position of the number to be deleted.\n
                                                                                `y_pos` (int): y position of the number to be deleted.\n
                                                                                `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        try: move_type = kwargs[&#39;move_type&#39;]
                                                                        except:  move_type = &#39;&#39;
                                                                        if move_type != &#39;backwards&#39;:
                                                                                self.inserted_numbers.append([x_pos,y_pos,game.board[x_pos][y_pos],&#39;delete&#39;])
                                                                        game.board[x_pos][y_pos] = 0
                                                                        self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                        game.gameover = False</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Body.DrawGrid"><code class="name flex">
                                                        <span>def <span class="ident">DrawGrid</span></span>(<span>self)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to draw sudoku board grid. </p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def DrawGrid(self):
                                                                        &#34;&#34;&#34;Method to draw sudoku board grid. 
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        for i in range(0,10):
                                                                                x = i * CELL_SIZE
                                                                                if i % 3 == 0:
                                                                                        self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, width=2)
                                                                                        self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, width=2)
                                                                                else:
                                                                                        pass
                                                                                        self.create_line(x + 4, 2, x + 4, HEIGHT-1, fill=GRID_COLOR, dash=(1,1))
                                                        self.create_line(2, x + 4, WIDTH-1, x + 4, fill=GRID_COLOR, dash=(1,1))</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Body.DrawNumbers"><code class="name flex">
                                                        <span>def <span class="ident">DrawNumbers</span></span>(<span>self, board, color)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to draw original (i.e. loaded) sudoku board numbers. </p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.</p>
                                                        <p><code>board</code> (matrix): valid sudoku board, loaded at the beginning of the program.</p>
                                                        <p><code>color</code> (str): <code><a title="tk_sudoku_game.GRID_COLOR" href="#tk_sudoku_game.GRID_COLOR">GRID_COLOR</a></code> colour.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def DrawNumbers(self,board,color):
                                                                        &#34;&#34;&#34;Method to draw original (i.e. loaded) sudoku board numbers. 
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `board` (matrix): valid sudoku board, loaded at the beginning of the program.\n
                                                                                `color` (str): `GRID_COLOR` colour.\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.delete(&#39;numbers&#39;)
                                                                        # delete all numbers with tag &#39;numbers&#39;
                                                                        for i in range(9):
                                                                                for j in range(9):
                                                                                        x, y = i * CELL_SIZE + CELL_SIZE / 2 + 4, j * CELL_SIZE + CELL_SIZE / 2 + 4
                                                                                        n = board[i][j]
                                                                                        if n != 0:
                                                        self.create_text(x, y, text=n, tags=&#39;numbers&#39;,fill=GRID_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Body.InsertMiddleText"><code class="name flex">
                                                        <span>def <span class="ident">InsertMiddleText</span></span>(<span>self, text)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to insert a text in the middle of <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code>.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.</p>
                                                        <p><code>text</code> (str): text to be inserted/drawn object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def InsertMiddleText(self,text):
                                                                        &#34;&#34;&#34;Method to insert a text in the middle of `Body`.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `text` (str): text to be inserted/drawn object.\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.delete(&#39;cursor&#39;)
                                                                        text = self.create_text(WIDTH / 2,HEIGHT / 2 - int(CELL_SIZE/2), text=text, font=(FONT_TYPE, int(CELL_SIZE/2)),fill=CURSOR_COLOR,tags=&#39;gameover&#39;)
                                                                        rect = self.create_rectangle(self.bbox(text),fill=BACKGROUND_COLOR,tags=&#39;gameover&#39;)
                                                        self.tag_lower(rect,text)</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Body.InsertNumber"><code class="name flex">
                                                        <span>def <span class="ident">InsertNumber</span></span>(<span>self, key, game, x_pos, y_pos, **kwargs)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to draw the inserted number in a valid position of the sudoku board.
                                                        The number will only be inserted if the position on <code>original_board</code> is <code>0</code>, <code>PossibleMove</code> returns True and if the number is not <code>0</code>.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.</p>
                                                        <p><code>key</code> (str): comes from binder. If not an integer, it will be ignored.</p>
                                                        <p><code>game</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                        <p><code>x_pos</code> (int): x position of the number to be inserted.</p>
                                                        <p><code>y_pos</code> (int): y position of the number to be inserted.</p>
                                                        <p><code>kwargs['move_type']</code> (str): if <code>backwards</code> does not update <code>inserted_numbers</code></p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def InsertNumber(self,key,game,x_pos,y_pos,**kwargs):
                                                                        &#34;&#34;&#34;Method to draw the inserted number in a valid position of the sudoku board.
                                                                        The number will only be inserted if the position on `original_board` is `0`, `PossibleMove` returns True and if the number is not `0`.
                                                                        
                                                                        Args:
                                                                                `self` (Body): `Body` object.\n
                                                                                `key` (str): comes from binder. If not an integer, it will be ignored.\n
                                                                                `game` (Game): `Game` object.\n
                                                                                `x_pos` (int): x position of the number to be inserted.\n
                                                                                `y_pos` (int): y position of the number to be inserted.\n
                                                                                `kwargs[&#39;move_type&#39;]` (str): if `backwards` does not update `inserted_numbers`\n
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        x, y = 4 + x_pos * CELL_SIZE + CELL_SIZE / 2, 4 + y_pos * CELL_SIZE + CELL_SIZE / 2
                                                                        try: move_type = kwargs[&#39;move_type&#39;]
                                                                        except:  move_type = &#39;&#39;
                                                                        try: int(key)
                                                                        except: pass
                                                                        else:
                                                                                number = int(key)
                                                                                if game.PossibleMove(number,x_pos,y_pos) and game.original_board[x_pos][y_pos] == 0 and number != 0:
                                                                                        self.delete(f&#39;number{x_pos}x{y_pos}&#39;)
                                                                                        game.board[x_pos][y_pos] = number
                                                                                        self.create_text(x, y, text=number, tags=f&#39;number{x_pos}x{y_pos}&#39;, fill=NUMBER_COLOR, font=(FONT_TYPE,int(CELL_SIZE/3)))
                                                                                        if move_type != &#39;backwards&#39;:
                                                        self.inserted_numbers.append([x_pos,y_pos,number,&#39;insert&#39;])</code></pre>
                                                        </details>
                                                        </dd>
                                                </dl>
                                                </dd>
                                                <dt id="tk_sudoku_game.Buttons"><code class="flex name class">
                                                <span>class <span class="ident">Buttons</span></span>
                                                <span>(</span><span>mainwindow)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Frame widget which contains the buttons. Has the <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object as argument.</p>
                                                <p>Uses super class <code>Frame</code> from module <code>tkinter</code></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">class Buttons(Frame):
                                                                &#34;&#34;&#34;Frame widget which contains the buttons. Has the `MainWindow` object as argument.
                                                                &#34;&#34;&#34;
                                                                def __init__(self,mainwindow):
                                                                        &#34;&#34;&#34;Uses super class `Frame` from module `tkinter`&#34;&#34;&#34;
                                                                        Frame.__init__(self)
                                                                        &#34;&#34;&#34;Initiates Frame instance in self.&#34;&#34;&#34;
                                                                        self.clear_button = ttk.Button(self, text=&#39;Clear numbers&#39;,command=lambda: self.ClearBoard(mainwindow))
                                                                        &#34;&#34;&#34;Button that call `ClearBoard` method&#34;&#34;&#34;
                                                                        self.solve_button = ttk.Button(self, text=&#39;Solve sudoku&#39;,command=lambda: self.SolveBoard(mainwindow))
                                                                        &#34;&#34;&#34;Button that call `SolveBoard` method&#34;&#34;&#34;
                                                                        self.back_button = ttk.Button(self, text=&#39;Move back&#39;,command=lambda: self.MoveBackwards(mainwindow))
                                                                        &#34;&#34;&#34;Button that call `MoveBackwards` method&#34;&#34;&#34;
                                                                def ClearBoard(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to clear/reset `board`. Calls `HardReset` method.
                                                                
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        WaitThread()
                                                                        mainwindow.HardReset()
                                                                        print(&#39;board cleared&#39;)
                                                                def SolveBoard(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws the solution (if it exists).
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        WaitThread()
                                                                        game = mainwindow.game
                                                                        game.solutions = deepcopy(game.original_solutions)
                                                                        game.RemoveInvalidSolutions()
                                                                        if game.solutions == []:
                                                                                mainwindow.body.InsertMiddleText(&#39;No possible solutions&#39;)
                                                                        else:
                                                                                mainwindow.body.delete(&#39;gameover&#39;)
                                                                                r = randint(0,len(game.solutions)-1)
                                                                                for x in range(9):
                                                                                        for y in range(9):
                                                                                                if game.solutions[r][x][y] != game.original_board[x][y]:
                                                                                                        mainwindow.body.InsertNumber(game.solutions[r][x][y],game,x,y)
                                                                def MoveBackwards(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws a solution (if there are any).
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        if mainwindow.body.inserted_numbers != []:
                                                                                last_move = mainwindow.body.inserted_numbers[-1]
                                                                                if last_move[-1] == &#39;insert&#39;:
                                                                                        mainwindow.body.DeleteNumber(mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                                elif last_move[-1] == &#39;delete&#39;:
                                                                                        mainwindow.body.InsertNumber(last_move[2],mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                                mainwindow.body.inserted_numbers = mainwindow.body.inserted_numbers[0:-1]
                                                                        mainwindow.body.delete(&#39;gameover&#39;)
                                                                        
                                                                def DrawButtons(self):
                                                                        &#34;&#34;&#34;Method to pack all buttons&#34;&#34;&#34;
                                                                        self.clear_button.pack(fill=X)
                                                                        self.solve_button.pack(fill=X)
                                                self.back_button.pack(fill=X)</code></pre>
                                                </details>
                                                <h3>Ancestors</h3>
                                                <ul class="hlist">
                                                        <li>tkinter.Frame</li>
                                                        <li>tkinter.Widget</li>
                                                        <li>tkinter.BaseWidget</li>
                                                        <li>tkinter.Misc</li>
                                                        <li>tkinter.Pack</li>
                                                        <li>tkinter.Place</li>
                                                        <li>tkinter.Grid</li>
                                                </ul>
                                                <h3>Instance variables</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Buttons.back_button"><code class="name">var <span class="ident">back_button</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Button that call <code>MoveBackwards</code> method</p></div>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Buttons.clear_button"><code class="name">var <span class="ident">clear_button</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Button that call <code>ClearBoard</code> method</p></div>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Buttons.solve_button"><code class="name">var <span class="ident">solve_button</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Button that call <code>SolveBoard</code> method</p></div>
                                                        </dd>
                                                </dl>
                                                <h3>Methods</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Buttons.ClearBoard"><code class="name flex">
                                                        <span>def <span class="ident">ClearBoard</span></span>(<span>self, mainwindow)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to clear/reset <code>board</code>. Calls <code>HardReset</code> method.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Buttons): <code><a title="tk_sudoku_game.Buttons" href="#tk_sudoku_game.Buttons">Buttons</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def ClearBoard(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to clear/reset `board`. Calls `HardReset` method.
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        WaitThread()
                                                                        mainwindow.HardReset()
                                                        print(&#39;board cleared&#39;)</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Buttons.DrawButtons"><code class="name flex">
                                                        <span>def <span class="ident">DrawButtons</span></span>(<span>self)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to pack all buttons</p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def DrawButtons(self):
                                                                        &#34;&#34;&#34;Method to pack all buttons&#34;&#34;&#34;
                                                                        self.clear_button.pack(fill=X)
                                                                        self.solve_button.pack(fill=X)
                                                        self.back_button.pack(fill=X)</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Buttons.MoveBackwards"><code class="name flex">
                                                        <span>def <span class="ident">MoveBackwards</span></span>(<span>self, mainwindow)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to print one random possible solution for the board. Calls method <code>RemoveInvalidSolutions</code> and draws a solution (if there are any).</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Buttons): <code><a title="tk_sudoku_game.Buttons" href="#tk_sudoku_game.Buttons">Buttons</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def MoveBackwards(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws a solution (if there are any).
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        if mainwindow.body.inserted_numbers != []:
                                                                                last_move = mainwindow.body.inserted_numbers[-1]
                                                                                if last_move[-1] == &#39;insert&#39;:
                                                                                        mainwindow.body.DeleteNumber(mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                                elif last_move[-1] == &#39;delete&#39;:
                                                                                        mainwindow.body.InsertNumber(last_move[2],mainwindow.game,last_move[0],last_move[1],move_type=&#39;backwards&#39;)
                                                                                mainwindow.body.inserted_numbers = mainwindow.body.inserted_numbers[0:-1]
                                                        mainwindow.body.delete(&#39;gameover&#39;)</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Buttons.SolveBoard"><code class="name flex">
                                                        <span>def <span class="ident">SolveBoard</span></span>(<span>self, mainwindow)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to print one random possible solution for the board. Calls method <code>RemoveInvalidSolutions</code> and draws the solution (if it exists).</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Buttons): <code><a title="tk_sudoku_game.Buttons" href="#tk_sudoku_game.Buttons">Buttons</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def SolveBoard(self,mainwindow):
                                                                        &#34;&#34;&#34;Method to print one random possible solution for the board. Calls method `RemoveInvalidSolutions` and draws the solution (if it exists).
                                                                        Args:
                                                                                `self` (Buttons): `Buttons` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        WaitThread()
                                                                        game = mainwindow.game
                                                                        game.solutions = deepcopy(game.original_solutions)
                                                                        game.RemoveInvalidSolutions()
                                                                        if game.solutions == []:
                                                                                mainwindow.body.InsertMiddleText(&#39;No possible solutions&#39;)
                                                                        else:
                                                                                mainwindow.body.delete(&#39;gameover&#39;)
                                                                                r = randint(0,len(game.solutions)-1)
                                                                                for x in range(9):
                                                                                        for y in range(9):
                                                                                                if game.solutions[r][x][y] != game.original_board[x][y]:
                                                        mainwindow.body.InsertNumber(game.solutions[r][x][y],game,x,y)</code></pre>
                                                        </details>
                                                        </dd>
                                                </dl>
                                                </dd>
                                                <dt id="tk_sudoku_game.Cursor"><code class="flex name class">
                                                <span>class <span class="ident">Cursor</span></span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Cursor widget to display/select the cells in the sudoku board.</p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">class Cursor(): 
                                                                &#34;&#34;&#34;Cursor widget to display/select the cells in the sudoku board.&#34;&#34;&#34;
                                                                def __init__(self):
                                                                        self.x_pos = 0
                                                                        &#34;&#34;&#34;Column position of the cursor&#34;&#34;&#34;
                                                                        self.y_pos = 0
                                                                        &#34;&#34;&#34;Row position of the cursor&#34;&#34;&#34;
                                                                        self.number = 0
                                                                def DrawCursor(self,body):
                                                                        &#34;&#34;&#34;Method to draw the cursor in positions `x_pos` and `y_pos`. 
                                                                        
                                                                        Args:
                                                                                `body` (Body): `Body` object.
                                                                                `self` (Cursor): `Cursor` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        x, y = 4 + (self.x_pos * CELL_SIZE), 4 + (self.y_pos * CELL_SIZE)
                                                                        body.delete(&#39;cursor&#39;)
                                                                        body.create_rectangle(x, y, x + CELL_SIZE, y + CELL_SIZE, outline=CURSOR_COLOR, tags=&#39;cursor&#39;,width=2)
                                                                def MoveCursor(self,event,window):
                                                                        &#34;&#34;&#34;Method to move cursor positions `x_pos` and `y_pos` according to the arrow keyboard input.
                                                                        The movement skips cells with numbers from original board.
                                                                        
                                                                        Args:
                                                                                `self` (Cursor): `Cursor` object.
                                                                                `body` (Window): `MainWindow` object.
                                                                                `event` (bind.event): event from `Tk.bind` method.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        moves = {&#39;Up&#39;:[0,-1],&#39;Down&#39;:[0,1],&#39;Left&#39;:[-1,0],&#39;Right&#39;:[1,0],}
                                                                        x, y = self.x_pos, self.y_pos
                                                                        while event.keysym in list(moves):
                                                                                x += moves[event.keysym][0]
                                                                                y += moves[event.keysym][1]
                                                                                if x &lt;= 8 and x &gt;= 0 and y &lt;= 8 and y &gt;= 0:
                                                                                        if window.game.original_board[x][y] == 0:
                                                                                                self.x_pos, self.y_pos = x, y
                                                                                                break
                                                                                else: break
                                                                        if window.game.original_board[self.x_pos][self.y_pos] == 0:
                                                self.DrawCursor(window.body)</code></pre>
                                                </details>
                                                <h3>Instance variables</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Cursor.x_pos"><code class="name">var <span class="ident">x_pos</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Column position of the cursor</p></div>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Cursor.y_pos"><code class="name">var <span class="ident">y_pos</span></code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Row position of the cursor</p></div>
                                                        </dd>
                                                </dl>
                                                <h3>Methods</h3>
                                                <dl>
                                                        <dt id="tk_sudoku_game.Cursor.DrawCursor"><code class="name flex">
                                                        <span>def <span class="ident">DrawCursor</span></span>(<span>self, body)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to draw the cursor in positions <code>x_pos</code> and <code>y_pos</code>. </p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>body</code> (Body): <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> object.
                                                        <code>self</code> (Cursor): <code><a title="tk_sudoku_game.Cursor" href="#tk_sudoku_game.Cursor">Cursor</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def DrawCursor(self,body):
                                                                        &#34;&#34;&#34;Method to draw the cursor in positions `x_pos` and `y_pos`. 
                                                                        
                                                                        Args:
                                                                                `body` (Body): `Body` object.
                                                                                `self` (Cursor): `Cursor` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        x, y = 4 + (self.x_pos * CELL_SIZE), 4 + (self.y_pos * CELL_SIZE)
                                                                        body.delete(&#39;cursor&#39;)
                                                        body.create_rectangle(x, y, x + CELL_SIZE, y + CELL_SIZE, outline=CURSOR_COLOR, tags=&#39;cursor&#39;,width=2)</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.Cursor.MoveCursor"><code class="name flex">
                                                        <span>def <span class="ident">MoveCursor</span></span>(<span>self, event, window)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method to move cursor positions <code>x_pos</code> and <code>y_pos</code> according to the arrow keyboard input.
                                                        The movement skips cells with numbers from original board.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (Cursor): <code><a title="tk_sudoku_game.Cursor" href="#tk_sudoku_game.Cursor">Cursor</a></code> object.
                                                        <code>body</code> (Window): <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object.
                                                <code>event</code> (bind.event): event from <code>Tk.bind</code> method.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def MoveCursor(self,event,window):
                                                                &#34;&#34;&#34;Method to move cursor positions `x_pos` and `y_pos` according to the arrow keyboard input.
                                                                The movement skips cells with numbers from original board.
                                                                
                                                                Args:
                                                                        `self` (Cursor): `Cursor` object.
                                                                        `body` (Window): `MainWindow` object.
                                                                        `event` (bind.event): event from `Tk.bind` method.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                moves = {&#39;Up&#39;:[0,-1],&#39;Down&#39;:[0,1],&#39;Left&#39;:[-1,0],&#39;Right&#39;:[1,0],}
                                                                x, y = self.x_pos, self.y_pos
                                                                while event.keysym in list(moves):
                                                                        x += moves[event.keysym][0]
                                                                        y += moves[event.keysym][1]
                                                                        if x &lt;= 8 and x &gt;= 0 and y &lt;= 8 and y &gt;= 0:
                                                                                if window.game.original_board[x][y] == 0:
                                                                                        self.x_pos, self.y_pos = x, y
                                                                                        break
                                                                        else: break
                                                                if window.game.original_board[self.x_pos][self.y_pos] == 0:
                                                self.DrawCursor(window.body)</code></pre>
                                                </details>
                                                </dd>
                                        </dl>
                                        </dd>
                                        <dt id="tk_sudoku_game.Game"><code class="flex name class">
                                        <span>class <span class="ident">Game</span></span>
                                        <span>(</span><span>board)</span>
                                        </code></dt>
                                        <dd>
                                        <div class="desc"><p>Contains all necessary info for the correct handling of the sudoku game.
                                        Takes one parameter <code>board</code> (a valid sudoku board) to be initiated.</p></div>
                                        <details class="source">
                                        <summary>
                                        <span>Expand source code</span>
                                        </summary>
                                        <pre><code class="python">class Game():
                                                        &#34;&#34;&#34;Contains all necessary info for the correct handling of the sudoku game.
                                                        Takes one parameter `board` (a valid sudoku board) to be initiated.&#34;&#34;&#34;
                                                        def __init__(self,board):
                                                                self.gameover = False
                                                                &#34;&#34;&#34;Boolean value to determine if the game is over&#34;&#34;&#34;
                                                                self.board = board
                                                                &#34;&#34;&#34;Valid sudoku board. Will be updated with the number inserted by the user.&#34;&#34;&#34;
                                                                self.original_board = deepcopy(board)
                                                                &#34;&#34;&#34;Copy of the `board` used to initiate the class. Will not change throughout the game.&#34;&#34;&#34;
                                                                self.original_solutions = []
                                                                &#34;&#34;&#34;Array with all possible solutions for the original board. It&#39;s calculated at the game start and will not change throughout the game.&#34;&#34;&#34;
                                                                self.solutions = []
                                                                &#34;&#34;&#34;Array with possible solutions for current `board` (i.e. board with inserted numbers.&#34;&#34;&#34;
                                                                Thread(target=self.SudokuSolver).start()
                                                                # Thread initiate to calculate all possible solutions for original board.
                                                        def PossibleMove(self, number, x_pos, y_pos):
                                                                &#34;&#34;&#34;Method to check if `number` can be inserted in positions `x_pos` &amp; `y_pos` of the `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.\n
                                                                        `number` (int): number to be inserted.\n
                                                                        `x_pos` (int): board column.\n
                                                                        `y_pos` (int): board row.\n
                                                                Returns:
                                                                        boolean: can `n` be inserted. _False_ if not possible. _True_ otherwise.
                                                                &#34;&#34;&#34;
                                                                for i in range(9):
                                                                        if self.board[x_pos][i] == number or self.board[i][y_pos] == number: return False
                                                                x_temp, y_temp = (x_pos//3)*3, (y_pos//3)*3
                                                                for i in range(3):
                                                                        for j in range(3):
                                                                                if self.board[x_temp+i][y_temp+j] == number: return False
                                                                return True
                                                        def RemoveInvalidSolutions(self):
                                                                &#34;&#34;&#34;Method to remove all invalid solutions for current `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def MatchSolution(board,solution):
                                                                        # Matches the solution with the board.
                                                                        # If solution cannot be applied to board, returns False
                                                                        for x in range(9):
                                                                                for y in range(9):
                                                                                        if board[x][y] != 0 and board[x][y] != solution[x][y]:
                                                                                                return False
                                                                        return True
                                                                for s in range(len(self.solutions)-1,-1,-1):
                                                                        # loops through all solutions and remove the invalid ones.
                                                                        if not MatchSolution(self.board,self.solutions[s]):
                                                                                del self.solutions[s]
                                                        def SudokuSolver(self):
                                                                &#34;&#34;&#34;Method to solve the sudoku board, inserting all solutions into `original_solutions`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def QueueBlank(board):
                                                                        # Creates a queue with the blank positions (i.e. `0`s) of grid and the quantity of blank spaces on its row, column and square.
                                                                        queue = {}
                                                                        blanks = 0
                                                                        for r in range(9):
                                                                                for c in range(9):
                                                                                        if board[r][c] == 0:
                                                                                                for i in range(9):
                                                                                                        if board[i][c] == 0: blanks += 1
                                                                                                        if board[r][i] == 0: blanks += 1
                                                                                                r_temp, c_temp = (r//3) * 3, (c//3) * 3
                                                                                                for i in range(3):
                                                                                                        for j in range(3):
                                                                                                                if board[r_temp+i][c_temp+j] == 0: blanks += 1
                                                                                        if blanks != 0: queue.update({(r,c):blanks})
                                                                                        blanks = 0
                                                                        temp_queue = sorted(queue.items(), key=lambda x: x[1])
                                                                        return [v[0] for v in temp_queue]
                                                                def SolveSudoku(queue):
                                                                        # Basic sudoku solver algorithm using recursion.
                                                                        if queue:
                                                                                row, col = queue[0][0], queue[0][1]
                                                                                for n in range(9):
                                                                                        if self.PossibleMove(n+1,row,col):
                                                                                                self.board[row][col] = n+1
                                                                                                SolveSudoku(queue[1:])
                                                                                                self.board[row][col] = 0
                                                                                return 
                                                                        solution = deepcopy(self.board)
                                                                        self.original_solutions.append(solution)
                                                                SolveSudoku(QueueBlank(self.board))
                                                                print(&#39;solutions thread finished&#39;)
                                                        def isGameOver(self):
                                                                &#34;&#34;&#34;Method to check there are `0` in board, if not the game is over. Stores the value in `gameover` variable of `Game`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                rows = []
                                                                for row in self.board: 
                                                                        rows += row
                                                                if 0 not in rows:
                                                                        self.gameover = True
                                                                else:
                                                                        self.gameover = False
                                                        def ResetGame(self):
                                                                &#34;&#34;&#34;Method to reset `board` to `original_board` and `solutions` to `original_solutions`.
                                                        
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.board = deepcopy(self.original_board)
                                        self.solutions = deepcopy(self.original_solutions)</code></pre>
                                        </details>
                                        <h3>Instance variables</h3>
                                        <dl>
                                                <dt id="tk_sudoku_game.Game.board"><code class="name">var <span class="ident">board</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Valid sudoku board. Will be updated with the number inserted by the user.</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.gameover"><code class="name">var <span class="ident">gameover</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Boolean value to determine if the game is over</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.original_board"><code class="name">var <span class="ident">original_board</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Copy of the <code>board</code> used to initiate the class. Will not change throughout the game.</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.original_solutions"><code class="name">var <span class="ident">original_solutions</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Array with all possible solutions for the original board. It's calculated at the game start and will not change throughout the game.</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.solutions"><code class="name">var <span class="ident">solutions</span></code></dt>
                                                <dd>
                                                <div class="desc"><p>Array with possible solutions for current <code>board</code> (i.e. board with inserted numbers.</p></div>
                                                </dd>
                                        </dl>
                                        <h3>Methods</h3>
                                        <dl>
                                                <dt id="tk_sudoku_game.Game.PossibleMove"><code class="name flex">
                                                <span>def <span class="ident">PossibleMove</span></span>(<span>self, number, x_pos, y_pos)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to check if <code>number</code> can be inserted in positions <code>x_pos</code> &amp; <code>y_pos</code> of the <code>board</code>.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                <p><code>number</code> (int): number to be inserted.</p>
                                                <p><code>x_pos</code> (int): board column.</p>
                                                <p><code>y_pos</code> (int): board row.</p>
                                                <h2 id="returns">Returns</h2>
                                                <dl>
                                                        <dt><code>boolean</code></dt>
                                                        <dd>can <code>n</code> be inserted. <em>False</em> if not possible. <em>True</em> otherwise.</dd>
                                                </dl></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def PossibleMove(self, number, x_pos, y_pos):
                                                                &#34;&#34;&#34;Method to check if `number` can be inserted in positions `x_pos` &amp; `y_pos` of the `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.\n
                                                                        `number` (int): number to be inserted.\n
                                                                        `x_pos` (int): board column.\n
                                                                        `y_pos` (int): board row.\n
                                                                Returns:
                                                                        boolean: can `n` be inserted. _False_ if not possible. _True_ otherwise.
                                                                &#34;&#34;&#34;
                                                                for i in range(9):
                                                                        if self.board[x_pos][i] == number or self.board[i][y_pos] == number: return False
                                                                x_temp, y_temp = (x_pos//3)*3, (y_pos//3)*3
                                                                for i in range(3):
                                                                        for j in range(3):
                                                                                if self.board[x_temp+i][y_temp+j] == number: return False
                                                return True</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.RemoveInvalidSolutions"><code class="name flex">
                                                <span>def <span class="ident">RemoveInvalidSolutions</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to remove all invalid solutions for current <code>board</code>.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def RemoveInvalidSolutions(self):
                                                                &#34;&#34;&#34;Method to remove all invalid solutions for current `board`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def MatchSolution(board,solution):
                                                                        # Matches the solution with the board.
                                                                        # If solution cannot be applied to board, returns False
                                                                        for x in range(9):
                                                                                for y in range(9):
                                                                                        if board[x][y] != 0 and board[x][y] != solution[x][y]:
                                                                                                return False
                                                                        return True
                                                                for s in range(len(self.solutions)-1,-1,-1):
                                                                        # loops through all solutions and remove the invalid ones.
                                                                        if not MatchSolution(self.board,self.solutions[s]):
                                                del self.solutions[s]</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.ResetGame"><code class="name flex">
                                                <span>def <span class="ident">ResetGame</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to reset <code>board</code> to <code>original_board</code> and <code>solutions</code> to <code>original_solutions</code>.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def ResetGame(self):
                                                                &#34;&#34;&#34;Method to reset `board` to `original_board` and `solutions` to `original_solutions`.
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.board = deepcopy(self.original_board)
                                                self.solutions = deepcopy(self.original_solutions)</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.SudokuSolver"><code class="name flex">
                                                <span>def <span class="ident">SudokuSolver</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to solve the sudoku board, inserting all solutions into <code>original_solutions</code>.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def SudokuSolver(self):
                                                                &#34;&#34;&#34;Method to solve the sudoku board, inserting all solutions into `original_solutions`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def QueueBlank(board):
                                                                        # Creates a queue with the blank positions (i.e. `0`s) of grid and the quantity of blank spaces on its row, column and square.
                                                                        queue = {}
                                                                        blanks = 0
                                                                        for r in range(9):
                                                                                for c in range(9):
                                                                                        if board[r][c] == 0:
                                                                                                for i in range(9):
                                                                                                        if board[i][c] == 0: blanks += 1
                                                                                                        if board[r][i] == 0: blanks += 1
                                                                                                r_temp, c_temp = (r//3) * 3, (c//3) * 3
                                                                                                for i in range(3):
                                                                                                        for j in range(3):
                                                                                                                if board[r_temp+i][c_temp+j] == 0: blanks += 1
                                                                                        if blanks != 0: queue.update({(r,c):blanks})
                                                                                        blanks = 0
                                                                        temp_queue = sorted(queue.items(), key=lambda x: x[1])
                                                                        return [v[0] for v in temp_queue]
                                                                def SolveSudoku(queue):
                                                                        # Basic sudoku solver algorithm using recursion.
                                                                        if queue:
                                                                                row, col = queue[0][0], queue[0][1]
                                                                                for n in range(9):
                                                                                        if self.PossibleMove(n+1,row,col):
                                                                                                self.board[row][col] = n+1
                                                                                                SolveSudoku(queue[1:])
                                                                                                self.board[row][col] = 0
                                                                                return 
                                                                        solution = deepcopy(self.board)
                                                                        self.original_solutions.append(solution)
                                                                SolveSudoku(QueueBlank(self.board))
                                                print(&#39;solutions thread finished&#39;)</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.Game.isGameOver"><code class="name flex">
                                                <span>def <span class="ident">isGameOver</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to check there are <code>0</code> in board, if not the game is over. Stores the value in <code>gameover</code> variable of <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code>.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (Game): <code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def isGameOver(self):
                                                                &#34;&#34;&#34;Method to check there are `0` in board, if not the game is over. Stores the value in `gameover` variable of `Game`.
                                                                
                                                                Args:
                                                                        `self` (Game): `Game` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                rows = []
                                                                for row in self.board: 
                                                                        rows += row
                                                                if 0 not in rows:
                                                                        self.gameover = True
                                                                else:
                                                self.gameover = False</code></pre>
                                                </details>
                                                </dd>
                                        </dl>
                                        </dd>
                                        <dt id="tk_sudoku_game.MainWindow"><code class="flex name class">
                                        <span>class <span class="ident">MainWindow</span></span>
                                        <span>(</span><span>board)</span>
                                        </code></dt>
                                        <dd>
                                        <div class="desc"><p>Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.</p>
                                        <p>It's the main game window that contains the sudoku game, sudoku frame (where numbers and grid will be drawn)
                                        and buttons frame (where the buttons will be packed).</p>
                                        <p>Uses super class <code>Tk</code> from module <code>tkinter</code></p></div>
                                        <details class="source">
                                        <summary>
                                        <span>Expand source code</span>
                                        </summary>
                                        <pre><code class="python">class MainWindow(Tk):
                                                        &#34;&#34;&#34;Toplevel widget of Tk which represents mostly the main window of an application. It has an associated Tcl interpreter.&#34;&#34;&#34;
                                                        def __init__(self,board):
                                                                &#34;&#34;&#34;It&#39;s the main game window that contains the sudoku game, sudoku frame (where numbers and grid will be drawn)
                                                                and buttons frame (where the buttons will be packed).
                                                                Uses super class `Tk` from module `tkinter`
                                                                &#34;&#34;&#34;
                                                                Tk.__init__(self)
                                                                # Initiates the Tk instance in self
                                                                self.body = Body()
                                                                &#34;&#34;&#34;`Body` class&#34;&#34;&#34;
                                                                self.cursor = Cursor()
                                                                &#34;&#34;&#34;`Cursor` class&#34;&#34;&#34;
                                                                self.game = Game(InvertBoard(board))
                                                                &#34;&#34;&#34;`Game` class with `InvertBoard`&#34;&#34;&#34;
                                                                self.buttons = Buttons(self)
                                                                &#34;&#34;&#34;`Cursor` class&#34;&#34;&#34;
                                                                self.Config()
                                                                &#34;&#34;&#34;Calls `Config` to configure the window&#34;&#34;&#34;
                                                                self.InitiateGame()
                                                                &#34;&#34;&#34;Calls `InitiateGame` to start the sudoku game&#34;&#34;&#34;
                                                        def Config(self):
                                                                &#34;&#34;&#34;Method called when `MainWindow` instance is initiate. Configures title, window size and background colour.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.title(&#39;SUDOKU&#39;)
                                                                self.geometry(f&#39;{WIDTH+2}x{HEIGHT+2 + BUTTONS_SIZE}&#39;)
                                                                self.config(bg=BACKGROUND_COLOR)
                                                                print(&#39;main window loaded and configured&#39;)
                                                        def InitiateGame(self):
                                                                &#34;&#34;&#34;Method called when the games starts or is reset with clear board button.
                                                                It calls `Binder`, `DrawGrid`, `DrawNumbers` (with `original_board`), `DrawButtons` and, packs `body` and `buttons`.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.Binder()
                                                                self.body.DrawGrid()
                                                                self.body.DrawNumbers(self.game.original_board,GRID_COLOR)
                                                                self.buttons.DrawButtons()
                                                                self.body.pack(fill=X)
                                                                self.buttons.pack(fill=X)
                                                                print(&#39;game initiated&#39;)
                                                        def Binder(self):
                                                                &#34;&#34;&#34;Method to bind/map keyboard and mouse clicks to their methods.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def __MoveHandler(event,window=self):
                                                                        # Gets the mouse position and moves/draws the cursor there
                                                                        if str(event.type) == &#39;ButtonPress&#39;:
                                                                                x, y = int((event.x) / CELL_SIZE), int((event.y) / CELL_SIZE)
                                                                                if x &gt; 8: x = 8
                                                                                if y &gt; 8: y = 8
                                                                                self.cursor.x_pos, self.cursor.y_pos = x, y
                                                                        self.cursor.MoveCursor(event,window)
                                                                def __InsertHandler(event):
                                                                        # Gets the stroked key and handles what to do with it
                                                                        if event.keysym == &#39;Escape&#39;: self.HardReset()
                                                                        if event.keysym == &#39;BackSpace&#39;:self.body.DeleteNumber(self.game, self.cursor.x_pos,self.cursor.y_pos)
                                                                        elif not self.game.gameover: self.body.InsertNumber(event.keysym,self.game,self.cursor.x_pos,self.cursor.y_pos)
                                                                        
                                                                        self.game.isGameOver()
                                                                        #  Checks if the game is over and draws the game over text
                                                                        if self.game.gameover:
                                                                                self.body.InsertMiddleText(&#39;Game over&#39;)
                                                                        else:
                                                                                self.body.delete(&#39;gameover&#39;)
                                                                self.body.bind(&#39;&lt;Button-1&gt;&#39;,__MoveHandler)
                                                                for key in [&#39;&lt;Left&gt;&#39;,&#39;&lt;Right&gt;&#39;,&#39;&lt;Up&gt;&#39;,&#39;&lt;Down&gt;&#39;]:
                                                                        self.bind(key,__MoveHandler)
                                                                self.bind(&#39;&lt;Key&gt;&#39;,__InsertHandler)
                                                        def HardReset(self):
                                                                &#34;&#34;&#34;Method to completely reset the game. 
                                                                Calls `ResetGame`, delete everything inside `Body` frame and reset `inserted_numbers` array.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.game.ResetGame()
                                                                self.body.delete(ALL)
                                                                self.body.inserted_numbers = []
                                        self.InitiateGame()</code></pre>
                                        </details>
                                        <h3>Ancestors</h3>
                                        <ul class="hlist">
                                                <li>tkinter.Tk</li>
                                                <li>tkinter.Misc</li>
                                                <li>tkinter.Wm</li>
                                        </ul>
                                        <h3>Instance variables</h3>
                                        <dl>
                                                <dt id="tk_sudoku_game.MainWindow.body"><code class="name">var <span class="ident">body</span></code></dt>
                                                <dd>
                                                <div class="desc"><p><code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> class</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.MainWindow.buttons"><code class="name">var <span class="ident">buttons</span></code></dt>
                                                <dd>
                                                <div class="desc"><p><code><a title="tk_sudoku_game.Cursor" href="#tk_sudoku_game.Cursor">Cursor</a></code> class</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.MainWindow.cursor"><code class="name">var <span class="ident">cursor</span></code></dt>
                                                <dd>
                                                <div class="desc"><p><code><a title="tk_sudoku_game.Cursor" href="#tk_sudoku_game.Cursor">Cursor</a></code> class</p></div>
                                                </dd>
                                                <dt id="tk_sudoku_game.MainWindow.game"><code class="name">var <span class="ident">game</span></code></dt>
                                                <dd>
                                                <div class="desc"><p><code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code> class with <code><a title="tk_sudoku_game.InvertBoard" href="#tk_sudoku_game.InvertBoard">InvertBoard()</a></code></p></div>
                                                </dd>
                                        </dl>
                                        <h3>Methods</h3>
                                        <dl>
                                                <dt id="tk_sudoku_game.MainWindow.Binder"><code class="name flex">
                                                <span>def <span class="ident">Binder</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to bind/map keyboard and mouse clicks to their methods.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (MainWindow): <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def Binder(self):
                                                                &#34;&#34;&#34;Method to bind/map keyboard and mouse clicks to their methods.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                def __MoveHandler(event,window=self):
                                                                        # Gets the mouse position and moves/draws the cursor there
                                                                        if str(event.type) == &#39;ButtonPress&#39;:
                                                                                x, y = int((event.x) / CELL_SIZE), int((event.y) / CELL_SIZE)
                                                                                if x &gt; 8: x = 8
                                                                                if y &gt; 8: y = 8
                                                                                self.cursor.x_pos, self.cursor.y_pos = x, y
                                                                        self.cursor.MoveCursor(event,window)
                                                                def __InsertHandler(event):
                                                                        # Gets the stroked key and handles what to do with it
                                                                        if event.keysym == &#39;Escape&#39;: self.HardReset()
                                                                        if event.keysym == &#39;BackSpace&#39;:self.body.DeleteNumber(self.game, self.cursor.x_pos,self.cursor.y_pos)
                                                                        elif not self.game.gameover: self.body.InsertNumber(event.keysym,self.game,self.cursor.x_pos,self.cursor.y_pos)
                                                                        
                                                                        self.game.isGameOver()
                                                                        #  Checks if the game is over and draws the game over text
                                                                        if self.game.gameover:
                                                                                self.body.InsertMiddleText(&#39;Game over&#39;)
                                                                        else:
                                                                                self.body.delete(&#39;gameover&#39;)
                                                                self.body.bind(&#39;&lt;Button-1&gt;&#39;,__MoveHandler)
                                                                for key in [&#39;&lt;Left&gt;&#39;,&#39;&lt;Right&gt;&#39;,&#39;&lt;Up&gt;&#39;,&#39;&lt;Down&gt;&#39;]:
                                                                        self.bind(key,__MoveHandler)
                                                self.bind(&#39;&lt;Key&gt;&#39;,__InsertHandler)</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.MainWindow.Config"><code class="name flex">
                                                <span>def <span class="ident">Config</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method called when <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> instance is initiate. Configures title, window size and background colour.</p>
                                                <h2 id="args">Args</h2>
                                                <p><code>self</code> (MainWindow): <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object.</p>
                                                <h2 id="returns">Returns</h2>
                                                <p><strong>None</strong></p></div>
                                                <details class="source">
                                                <summary>
                                                <span>Expand source code</span>
                                                </summary>
                                                <pre><code class="python">def Config(self):
                                                                &#34;&#34;&#34;Method called when `MainWindow` instance is initiate. Configures title, window size and background colour.
                                                                
                                                                Args:
                                                                        `self` (MainWindow): `MainWindow` object.
                                                                Returns:
                                                                        __None__
                                                                &#34;&#34;&#34;
                                                                self.title(&#39;SUDOKU&#39;)
                                                                self.geometry(f&#39;{WIDTH+2}x{HEIGHT+2 + BUTTONS_SIZE}&#39;)
                                                                self.config(bg=BACKGROUND_COLOR)
                                                print(&#39;main window loaded and configured&#39;)</code></pre>
                                                </details>
                                                </dd>
                                                <dt id="tk_sudoku_game.MainWindow.HardReset"><code class="name flex">
                                                <span>def <span class="ident">HardReset</span></span>(<span>self)</span>
                                                </code></dt>
                                                <dd>
                                                <div class="desc"><p>Method to completely reset the game.
                                                        Calls <code>ResetGame</code>, delete everything inside <code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code> frame and reset <code>inserted_numbers</code> array.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (MainWindow): <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def HardReset(self):
                                                                        &#34;&#34;&#34;Method to completely reset the game. 
                                                                        Calls `ResetGame`, delete everything inside `Body` frame and reset `inserted_numbers` array.
                                                                        
                                                                        Args:
                                                                                `self` (MainWindow): `MainWindow` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.game.ResetGame()
                                                                        self.body.delete(ALL)
                                                                        self.body.inserted_numbers = []
                                                        self.InitiateGame()</code></pre>
                                                        </details>
                                                        </dd>
                                                        <dt id="tk_sudoku_game.MainWindow.InitiateGame"><code class="name flex">
                                                        <span>def <span class="ident">InitiateGame</span></span>(<span>self)</span>
                                                        </code></dt>
                                                        <dd>
                                                        <div class="desc"><p>Method called when the games starts or is reset with clear board button.
                                                        It calls <code>Binder</code>, <code>DrawGrid</code>, <code>DrawNumbers</code> (with <code>original_board</code>), <code>DrawButtons</code> and, packs <code>body</code> and <code>buttons</code>.</p>
                                                        <h2 id="args">Args</h2>
                                                        <p><code>self</code> (MainWindow): <code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code> object.</p>
                                                        <h2 id="returns">Returns</h2>
                                                        <p><strong>None</strong></p></div>
                                                        <details class="source">
                                                        <summary>
                                                        <span>Expand source code</span>
                                                        </summary>
                                                        <pre><code class="python">def InitiateGame(self):
                                                                        &#34;&#34;&#34;Method called when the games starts or is reset with clear board button.
                                                                        It calls `Binder`, `DrawGrid`, `DrawNumbers` (with `original_board`), `DrawButtons` and, packs `body` and `buttons`.
                                                                        
                                                                        Args:
                                                                                `self` (MainWindow): `MainWindow` object.
                                                                        Returns:
                                                                                __None__
                                                                        &#34;&#34;&#34;
                                                                        self.Binder()
                                                                        self.body.DrawGrid()
                                                                        self.body.DrawNumbers(self.game.original_board,GRID_COLOR)
                                                                        self.buttons.DrawButtons()
                                                                        self.body.pack(fill=X)
                                                                        self.buttons.pack(fill=X)
                                                        print(&#39;game initiated&#39;)</code></pre>
                                                        </details>
                                                        </dd>
                                                </dl>
                                                </dd>
                                        </dl>
                                </section>
                        </article>
                        <nav id="sidebar">
                                <h1>Index</h1>
                                <div class="toc">
                                <ul></ul>
                        </div>
                        <ul id="index">
                                <li><h3><a href="#header-variables">Global variables</a></h3>
                                <ul class="two-column">
                                        <li><code><a title="tk_sudoku_game.BACKGROUND_COLOR" href="#tk_sudoku_game.BACKGROUND_COLOR">BACKGROUND_COLOR</a></code></li>
                                        <li><code><a title="tk_sudoku_game.CELL_SIZE" href="#tk_sudoku_game.CELL_SIZE">CELL_SIZE</a></code></li>
                                        <li><code><a title="tk_sudoku_game.CURSOR_COLOR" href="#tk_sudoku_game.CURSOR_COLOR">CURSOR_COLOR</a></code></li>
                                        <li><code><a title="tk_sudoku_game.FONT_TYPE" href="#tk_sudoku_game.FONT_TYPE">FONT_TYPE</a></code></li>
                                        <li><code><a title="tk_sudoku_game.GRID_COLOR" href="#tk_sudoku_game.GRID_COLOR">GRID_COLOR</a></code></li>
                                        <li><code><a title="tk_sudoku_game.NUMBER_COLOR" href="#tk_sudoku_game.NUMBER_COLOR">NUMBER_COLOR</a></code></li>
                                </ul>
                        </li>
                        <li><h3><a href="#header-functions">Functions</a></h3>
                        <ul class="">
                                <li><code><a title="tk_sudoku_game.InvertBoard" href="#tk_sudoku_game.InvertBoard">InvertBoard</a></code></li>
                                <li><code><a title="tk_sudoku_game.WaitThread" href="#tk_sudoku_game.WaitThread">WaitThread</a></code></li>
                        </ul>
                </li>
                <li><h3><a href="#header-classes">Classes</a></h3>
                <ul>
                        <li>
                                <h4><code><a title="tk_sudoku_game.Body" href="#tk_sudoku_game.Body">Body</a></code></h4>
                                <ul class="two-column">
                                        <li><code><a title="tk_sudoku_game.Body.DeleteNumber" href="#tk_sudoku_game.Body.DeleteNumber">DeleteNumber</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Body.DrawGrid" href="#tk_sudoku_game.Body.DrawGrid">DrawGrid</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Body.DrawNumbers" href="#tk_sudoku_game.Body.DrawNumbers">DrawNumbers</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Body.InsertMiddleText" href="#tk_sudoku_game.Body.InsertMiddleText">InsertMiddleText</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Body.InsertNumber" href="#tk_sudoku_game.Body.InsertNumber">InsertNumber</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Body.inserted_numbers" href="#tk_sudoku_game.Body.inserted_numbers">inserted_numbers</a></code></li>
                                </ul>
                        </li>
                        <li>
                                <h4><code><a title="tk_sudoku_game.Buttons" href="#tk_sudoku_game.Buttons">Buttons</a></code></h4>
                                <ul class="two-column">
                                        <li><code><a title="tk_sudoku_game.Buttons.ClearBoard" href="#tk_sudoku_game.Buttons.ClearBoard">ClearBoard</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.DrawButtons" href="#tk_sudoku_game.Buttons.DrawButtons">DrawButtons</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.MoveBackwards" href="#tk_sudoku_game.Buttons.MoveBackwards">MoveBackwards</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.SolveBoard" href="#tk_sudoku_game.Buttons.SolveBoard">SolveBoard</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.back_button" href="#tk_sudoku_game.Buttons.back_button">back_button</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.clear_button" href="#tk_sudoku_game.Buttons.clear_button">clear_button</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Buttons.solve_button" href="#tk_sudoku_game.Buttons.solve_button">solve_button</a></code></li>
                                </ul>
                        </li>
                        <li>
                                <h4><code><a title="tk_sudoku_game.Cursor" href="#tk_sudoku_game.Cursor">Cursor</a></code></h4>
                                <ul class="">
                                        <li><code><a title="tk_sudoku_game.Cursor.DrawCursor" href="#tk_sudoku_game.Cursor.DrawCursor">DrawCursor</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Cursor.MoveCursor" href="#tk_sudoku_game.Cursor.MoveCursor">MoveCursor</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Cursor.x_pos" href="#tk_sudoku_game.Cursor.x_pos">x_pos</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Cursor.y_pos" href="#tk_sudoku_game.Cursor.y_pos">y_pos</a></code></li>
                                </ul>
                        </li>
                        <li>
                                <h4><code><a title="tk_sudoku_game.Game" href="#tk_sudoku_game.Game">Game</a></code></h4>
                                <ul class="">
                                        <li><code><a title="tk_sudoku_game.Game.PossibleMove" href="#tk_sudoku_game.Game.PossibleMove">PossibleMove</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.RemoveInvalidSolutions" href="#tk_sudoku_game.Game.RemoveInvalidSolutions">RemoveInvalidSolutions</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.ResetGame" href="#tk_sudoku_game.Game.ResetGame">ResetGame</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.SudokuSolver" href="#tk_sudoku_game.Game.SudokuSolver">SudokuSolver</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.board" href="#tk_sudoku_game.Game.board">board</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.gameover" href="#tk_sudoku_game.Game.gameover">gameover</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.isGameOver" href="#tk_sudoku_game.Game.isGameOver">isGameOver</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.original_board" href="#tk_sudoku_game.Game.original_board">original_board</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.original_solutions" href="#tk_sudoku_game.Game.original_solutions">original_solutions</a></code></li>
                                        <li><code><a title="tk_sudoku_game.Game.solutions" href="#tk_sudoku_game.Game.solutions">solutions</a></code></li>
                                </ul>
                        </li>
                        <li>
                                <h4><code><a title="tk_sudoku_game.MainWindow" href="#tk_sudoku_game.MainWindow">MainWindow</a></code></h4>
                                <ul class="two-column">
                                        <li><code><a title="tk_sudoku_game.MainWindow.Binder" href="#tk_sudoku_game.MainWindow.Binder">Binder</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.Config" href="#tk_sudoku_game.MainWindow.Config">Config</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.HardReset" href="#tk_sudoku_game.MainWindow.HardReset">HardReset</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.InitiateGame" href="#tk_sudoku_game.MainWindow.InitiateGame">InitiateGame</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.body" href="#tk_sudoku_game.MainWindow.body">body</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.buttons" href="#tk_sudoku_game.MainWindow.buttons">buttons</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.cursor" href="#tk_sudoku_game.MainWindow.cursor">cursor</a></code></li>
                                        <li><code><a title="tk_sudoku_game.MainWindow.game" href="#tk_sudoku_game.MainWindow.game">game</a></code></li>
                                </ul>
                        </li>
                </ul>
        </li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.1</a>.</p>
</footer>
</body>
</html>